package com.nabicht.bigblankpage.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JLabel;
import javax.swing.JPanel;

import com.nabicht.utilities.keylistener.GeneratedKeyListener;

public class ProgramMenu extends PopupPanel implements ActionListener, FocusListener {

	
	private class MenuLabel extends JLabel {
		
		private Color notSelectedColor = new Color(40, 40, 40);
		private Color selectedColor = Color.WHITE;
		
		private boolean selected = false;
		private final String command;
		
		//TODO make font bigger
		
		public MenuLabel(String text, String command) {
			super(text);
			this.command = command;
			setSelected(selected);
			setOpaque(false);
			setBackground(new Color(0,0,0,0));
		}
		
		public void setSelected(boolean selected) {
			this.selected = selected;
			setForeground(selected ? selectedColor : notSelectedColor);
			repaint();
		}
		
		public boolean isSelected() {
			return selected;
		}
		
		public String getCommand() {
			return command;
		}
	}
	
	public static final String MENU_CLOSED_AC = "menu has been closed";
	public static final String SAVE_AC = "save active document";
	public static final String SAVE_AS_AC = "save active document as";
	public static final String OPEN_AC = "open a document";
	
	private List<ActionListener> actionListeners = new ArrayList<ActionListener>();
	
	private JPanel labelPanel = new JPanel();
	private ArrayList<MenuLabel> labels = new ArrayList<MenuLabel>();
	private GeneratedKeyListener keyListener;
	private int selectedIndex = 0;
	
	
	public ProgramMenu() {
		super(new BorderLayout());
		InputStream is = getClass().getClassLoader().getResourceAsStream("resources/MenuKeyListenerConfig.xml");
		keyListener = new GeneratedKeyListener(is);
		keyListener.addActionListener(this);
		labelPanel.setOpaque(false);
		addKeyListener(keyListener);
		setFocusable(true);
		initLabels();
		setSelected(0);
		
		for (MenuLabel label : labels) {
			labelPanel.add(label);
		}
		add(labelPanel, BorderLayout.CENTER);
		
		addFocusListener(this);
	}
	
	public void focusGained(FocusEvent fe) { }
	
	public void focusLost(FocusEvent fe) {
		this.requestFocus();
	}
	
	private void initLabels() {
		labels.add(new MenuLabel("Open", ProgramMenu.OPEN_AC));
		labels.add(new MenuLabel("Save", ProgramMenu.SAVE_AC));
		labels.add(new MenuLabel("Save As", ProgramMenu.SAVE_AS_AC));
	}
	
	public void actionPerformed(ActionEvent ae) {
		String cmd = ae.getActionCommand();
		if (cmd.equals("move right")) {
			incrementSelected();
		} else if (cmd.equals("move left")) {
			decrementSelected();
		} else if (cmd.equals("close menu")) {
			keyListener.setEnabled(false);
			notifyActionListeners(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, ProgramMenu.MENU_CLOSED_AC));
		} else if (cmd.equals("choose selected")) {
			String command = labels.get(selectedIndex).getCommand();
			//close menu
			keyListener.setEnabled(false);
			notifyActionListeners(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, ProgramMenu.MENU_CLOSED_AC));
			//do action
			notifyActionListeners(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, command));
		}
	}
	
	private void incrementSelected() {
		setSelected(selectedIndex + 1);
	}
	
	private void decrementSelected() {
		setSelected(selectedIndex - 1);
	}
	
	private void setSelected(int index) {
		labels.get(selectedIndex).setSelected(false);
		selectedIndex = index;
		if (index < 0) {
			selectedIndex = labels.size() - 1;
		} if (selectedIndex >= labels.size()) {
			selectedIndex = 0;
		}
		labels.get(selectedIndex).setSelected(true);
	}
	
	public synchronized void addActionListener(ActionListener listener) {
		actionListeners.add(listener);
	}
	
	private synchronized void notifyActionListeners(final ActionEvent ae) {
		for (ActionListener listener : actionListeners) {
			listener.actionPerformed(ae);
		}
	}
	
	
	//static menu generators//////////////////////////////////////////////////
	
	public static ProgramMenu getMenu() {
		//TODO eventually there will be different menus for differnet states.
		//and this is what that will be used for
		return new ProgramMenu();
	}
	
}
